package com.tjcd.project.library_base.common.utils;

import com.blankj.utilcode.util.LogUtils;

import java.util.concurrent.TimeUnit;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Scheduler;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.schedulers.Schedulers;

/**
 * @Author jiangKunKun
 * @CreateDate 2024/10/11
 * @Description
 * @SpittingGrooves
 */
public class RxJavaUtils {
    /**
     * 调度器io线程
     */
    private static final Scheduler IO_SCHEDULER = Schedulers.io();
    /**
     * 调度器主线程
     */
    private static final Scheduler MAIN_THREAD_SCHEDULER = AndroidSchedulers.mainThread();
    /**
     * 循环执行指定次数的任务，并在完成后执行完成后的动作。
     * 每次循环的间隔时间以指数增长。
     *
     * @param delay      初始延迟时间毫秒
     * @param loopCount  循环次数
     * @param interval   初始间隔时间（毫秒）
     * @param multiplier 每次间隔时间的倍数
     * @param action     每次循环执行的动作
     * @param onCompleteAction 完成后的动作
     * @return Disposable 对象，用于手动关闭
     */
    public static Disposable executeExponentialLoopFrequency(int delay, int loopCount, long interval, double multiplier, Runnable action, Runnable onCompleteAction) {
        return Observable.timer(delay, TimeUnit.MILLISECONDS)
                .concatMap(tick -> {
                    // 立即执行第一次循环
                    action.run();
                    return Observable.range(1, loopCount - 1) // 后续循环
                            .concatMap(i -> Observable.timer((long) (interval * Math.pow(multiplier, i - 1)), TimeUnit.MILLISECONDS)
                                    .doOnNext(j -> action.run()));
                })
                .doOnComplete(() -> {
                    if (onCompleteAction != null) {
                        onCompleteAction.run();
                    }
                })
                .doOnError(new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Throwable {
                        LogUtils.e("RxJavaUtils: " + throwable.toString());
                    }
                })
                .subscribeOn(IO_SCHEDULER)
                .observeOn(MAIN_THREAD_SCHEDULER)
                .subscribe();
    }

    /**
     * 循环执行指定次数的任务，并在完成后执行完成后的动作。
     * 每次循环的间隔时间以指数增长。
     *
     * @param loopCount  循环次数
     * @param interval   初始间隔时间（毫秒）
     * @param multiplier 每次间隔时间的倍数
     * @param action     每次循环执行的动作
     * @param onCompleteAction 完成后的动作
     * @return Disposable 对象，用于手动关闭
     */
    public static Disposable executeExponentialLoopFrequency(int loopCount, long interval, double multiplier, Runnable action, Runnable onCompleteAction) {
        return executeExponentialLoopFrequency(0, loopCount, interval, multiplier, action, onCompleteAction);
    }

    /**
     * 循环执行指定次数的任务，并在完成后执行完成后的动作。
     * 每次循环的间隔时间以指数增长。
     *
     * @param loopCount  循环次数
     * @param interval   初始间隔时间（毫秒）
     * @param multiplier 每次间隔时间的倍数
     * @param action     每次循环执行的动作
     * @return Disposable 对象，用于手动关闭
     */
    public static Disposable executeExponentialLoopFrequency(int loopCount, long interval, double multiplier, Runnable action) {
        return executeExponentialLoopFrequency(0, loopCount, interval, multiplier, action, null);
    }

    /**
     * 循环执行指定次数的任务，并在完成后执行完成后的动作。
     *
     * @param delay      延迟时间毫秒
     * @param loopCount      循环次数
     * @param interval       间隔时间（毫秒）
     * @param action         每次循环执行的动作
     * @param onCompleteAction 完成后的动作
     * @return Disposable 对象，用于手动关闭
     */
    public static Disposable executeDelayLoopFrequency(int delay, int loopCount, long interval, Runnable action, Runnable onCompleteAction) {
        return Observable.interval(delay, interval, TimeUnit.MILLISECONDS)
                .observeOn(MAIN_THREAD_SCHEDULER) // 在主线程上执行
                .take(loopCount)
                .doOnNext(i -> {
                    action.run();
                })
                .doOnComplete(() -> {
                    if (onCompleteAction != null) {
                        onCompleteAction.run();
                    }
                })
                .doOnError(new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Throwable {
                        LogUtils.e("RxJavaUtils: " + throwable.toString());
                    }
                })
                .subscribe();
    }
    /**
     * 循环执行指定次数的任务，并在完成后执行完成后的动作。
     *
     * @param delay      延迟时间毫秒
     * @param loopCount      循环次数
     * @param interval       间隔时间（毫秒）
     * @param action         每次循环执行的动作
     * @return Disposable 对象，用于手动关闭
     */
    public static Disposable executeDelayLoopFrequency(int delay, int loopCount, long interval, Runnable action) {
        return executeDelayLoopFrequency(delay, loopCount, interval, action, null);
    }
    /**
     * 循环执行指定次数的任务，并在完成后执行完成后的动作。
     *
     * @param loopCount      循环次数
     * @param interval       间隔时间（毫秒）
     * @param action         每次循环执行的动作
     * @param onCompleteAction 完成后的动作
     * @return Disposable 对象，用于手动关闭
     */
    public static Disposable executeLoopFrequency(int loopCount, long interval, Runnable action, Runnable onCompleteAction) {
        return executeDelayLoopFrequency(0, loopCount, interval, action, onCompleteAction);
    }

    /**
     * 循环执行指定次数的任务，但没有完成后的动作。
     *
     * @param loopCount  循环次数
     * @param interval   间隔时间（毫秒）
     * @param action     每次循环执行的动作
     * @return Disposable 对象，用于手动关闭
     */
    public static Disposable executeLoopFrequency(int loopCount, long interval, Runnable action) {
        return executeLoopFrequency(loopCount, interval, action, null);
    }

    /**
     * 循环执行任务，直到手动关闭。
     *
     * @param interval  间隔时间（毫秒）
     * @param action    每次循环执行的动作
     * @return Disposable 对象，用于手动关闭
     */
    public static Disposable executeLoop(long interval, Runnable action) {
        return executeLoop(0, interval, action);
    }
    /**
     * 循环执行指定次数的任务，但没有完成后的动作。
     *
     * @param delay  延迟时间毫秒
     * @param interval   间隔时间（毫秒）
     * @param action     每次循环执行的动作
     * @return Disposable 对象，用于手动关闭
     */
    public static Disposable executeLoop(int delay, long interval, Runnable action) {
        return Observable.interval(delay, interval, TimeUnit.MILLISECONDS)
                .observeOn(MAIN_THREAD_SCHEDULER) // 在主线程上执行
                .doOnNext(i -> {
                    action.run();
                })
                .doOnError(new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Throwable {
                        LogUtils.e("RxJavaUtils: " + throwable.toString());
                    }
                })
                .subscribe();
    }

    /**
     * application 调用
     *     RxJavaPlugins.setErrorHandler(new Consumer<Throwable>() {
     *             @Override
     *             public void accept(Throwable throwable) throws Throwable {
     *                 if (throwable instanceof SocketTimeoutException) {
     *                     // 处理超时异常
     *                     LogUtils.e("SocketTimeoutException: " + throwable.getMessage());
     *                 } else {
     *                     // 其他异常处理
     *                     LogUtils.e("Unhandled exception: " + throwable.getMessage());
     *                 }
     *             }
     *         });
     */
}
